#pragma once
#include "platform.hpp"

#if defined(JH_OS_WINDOWS)
#include <Windows.h>
#elif defined(JH_OS_LINUX)
#include <pthread.h>
#include <errno.h>
#endif

namespace JHCPP
{
	namespace event
	{
	#if defined(JH_OS_WINDOWS)
		class CSemaphoreImpl
		{
		protected:
			CSemaphoreImpl(int n, int max);		
			~CSemaphoreImpl();
			void setImpl();
			void waitImpl();
			bool waitImpl(long milliseconds);

		private:
			HANDLE m_sema;
		};
	#elif defined(JH_OS_LINUX)
		class CSemaphoreImpl
		{
		protected:
			CSemaphoreImpl(int n, int max);		
			~CSemaphoreImpl();
			void setImpl();
			void waitImpl();
			bool waitImpl(long milliseconds);

		private:
			volatile int    m_n;
			int             m_max;
			pthread_mutex_t m_mutex;
			pthread_cond_t  m_cond;
		};
	#endif

		class CSemaphore: private CSemaphoreImpl
		{
		public:
			CSemaphore(int n);
			CSemaphore(int n, int max);
			~CSemaphore();

			void set();
			void wait();
			void wait(long milliseconds);
			bool tryWait(long milliseconds);

		private:
			CSemaphore();
			CSemaphore(const CSemaphore&);
			CSemaphore& operator = (const CSemaphore&);
		};

	}//end of namespace event
}//end of namespace JHCPP
